home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / autodisk.arc / AUTODISK.C next >
C/C++ Source or Header  |  1986-12-23  |  7KB  |  233 lines

  1. /*
  2.  
  3.    AUTODISK - program to copy floppy disk to RAM disk upon system
  4.                 boot, and also set the system clock.
  5.    By Moshe Braner  <braner@amvax.tn.cornell.edu>          861223
  6.  
  7. FUNCTION
  8.    This program is to be placed in the \AUTO folder on the boot disk,
  9.    AFTER the RAMdisk program.  (It assumes the reset-immune RAM disk is
  10.    already installed.)  After asking the user for the current time and
  11.    date, and setting the ST's two clocks accordingly, this program copies
  12.    the whole floppy disk data, FATs, directory and all, onto the RAMdisk.
  13.    (It first finds out which sector is the last one actually holding data,
  14.    and copies all sectors up to that one.)
  15.  
  16. HINTS
  17.    For best results:  Freshly format a disk, make an AUTO directory,
  18.    put in it first RAMDISK.PRG and then AUTODISK.PRG, then put on the
  19.    disk all other files you want to load to the RAMdisk at boot time,
  20.    but no others.  You can set these files up in folders if you want:
  21.    first make the folders, then put the files on the disk directly into
  22.    the folders.  For maximum speed do not make any deletions of files,
  23.    nor copy files from the disk to itself.
  24.    You may save the desktop (with the RAMdisk icon installed, and perhaps
  25.    the RAMdisk's window open) on the disk, too.  Make sure the RAMdisk
  26.    is more than big enough to hold all those files.
  27.  
  28. ACKNOWLEDGEMENTS
  29.    This program made possible in part by Eric Terrell, who posted
  30.    "eternal.s".  The method of setting the ST's clocks is borrowed
  31.    from "settime", posted by Allan Pratt of Atari.
  32.  
  33. WARNINGS
  34.    This program is for booting off a floppy disk.  For hard disks (or
  35.    future, very large, floppies) the program (and/or the RAMdisk program)
  36.    needs some tweaking, at least at the points marked ">>>>".
  37.    This program will not work with "copy protected" disk formats,
  38.    including the "FAST" format with its "dead" sectors.
  39. */
  40.  
  41. #include <osbind.h>
  42.  
  43. #define SECSIZE    512    /* >>>> for now 512-byte sectors only */
  44.  
  45. #define WORD    int    /* 16 bits: 'int' in Megamax */
  46.  
  47. #define OK    0
  48. #define READ    0
  49.  
  50. /* read unsigned bytes and Intel-style integers */
  51. #define US(p,o)    (p[o]&0xFF)
  52. #define UI(p,o)    (US(p,o)+256*US(p,o+1))
  53.  
  54. #define fixup(s) (s[s[1]+2] = '\0')    /* null-terminate a GEMDOS string */
  55.  
  56. int
  57. strlen(s)
  58.     char *s;
  59. {
  60.     register int i=0;
  61.     while (s[i++]);
  62.     return (i-1);
  63. }
  64.  
  65. error(msg)
  66.     char msg[];
  67. {
  68.     Cconws(msg);
  69.     Cconws("\r\n\n\tHit any key ");
  70.     Cconin();
  71.     exit(0);
  72. }
  73.  
  74. int
  75. dotime(s)
  76.     register char *s;
  77. {
  78.     register int len;
  79.     register int hour, minute, second;
  80.  
  81.     len = strlen(s);
  82.     if (len < 4 || len == 5 || len > 6) goto badtime;
  83.  
  84.     hour = (s[0]-'0') * 10 + (s[1]-'0');
  85.     minute = (s[2]-'0') * 10 + (s[3]-'0');
  86.     if (len == 6) second = (s[4]-'0') * 10 + (s[5]-'0');
  87.     else second = 0;
  88.  
  89.     if (hour < 0 || hour > 23 ||
  90.         minute < 0 || minute > 59 ||
  91.         second < 0 || second > 59) goto badtime;
  92.  
  93.     if (Tsettime((hour << 11) + (minute << 5) + (second >> 1))==0)
  94.         return (0);
  95.  
  96. badtime:
  97.     Cconws("\r\nIllegal time (bad format or out of range)\r\n");
  98.     return (1);
  99. }
  100.  
  101. int
  102. dodate(s)
  103.     register char *s;
  104. {
  105.     register int len;
  106.     register int month,day,year;
  107.  
  108.     len = strlen(s);
  109.     if (len != 6) goto baddate;
  110.  
  111.     year =  (s[0]-'0') * 10 + (s[1]-'0') - 80;
  112.     month = (s[2]-'0') * 10 + (s[3]-'0');
  113.     day =   (s[4]-'0') * 10 + (s[5]-'0');
  114.  
  115.     if (year < 0 || year > 119 || 
  116.         month < 1 || month > 12 || 
  117.         day < 1 || day > 31) goto baddate;
  118.  
  119.     if (Tsetdate((year << 9) + (month << 5) + day)==0) return (0);
  120.  
  121. baddate:
  122.     Cconws("\r\nIllegal date (bad format or out of range)\r\n");
  123.     return (1);
  124. }
  125.  
  126. main()
  127. {
  128.     register int i, res, secs;
  129.     register char *buf;
  130.     int    bps, spc, fats, dir, spd, spf, spt, drive, sides;
  131.     WORD    date, time;
  132.     WORD    *bpb;
  133.     char    boot[SECSIZE], str[10];
  134.     long    stack, datime;
  135.     char    *msg = "\nError reading disk!";
  136.  
  137.     Cconws("\033E\r\n\n\tAUTODISK\tby Moshe Braner\r\n\n");
  138.  
  139.     /* see if IKBD time is valid */
  140.     datime = Gettime();        /* get ikbd date & time */
  141.     date = datime >> 16;
  142.     time = datime & 0xffff;
  143.  
  144.     if (((date & 0x1f) != 0) &&
  145.         (((date >> 5) & 0x0f) != 0))
  146.         if (Tsetdate(date)==0 && Tsettime(time)==0)
  147.             goto timedone;
  148.  
  149.     /* we want to prompt the user    */
  150.  
  151.     str[0] = 7;    /* set up buffer for Cconrs call */
  152.     do {
  153.         Cconws("\r\n\tEnter the time (hhmm[ss]): ");
  154.         Cconrs(str);
  155.         fixup(str);
  156.     } while (dotime(str+2));
  157.  
  158.     do {
  159.         Cconws("\r\n\tEnter the date (yymmdd): ");
  160.         Cconrs(str);
  161.         fixup(str);
  162.     } while (dodate(str+2));
  163.  
  164.     datime = ((long)Tgetdate() << 16) + Tgettime();    /* get GEM's time */
  165.     Settime(datime);            /* update the ikbd's time */
  166.     Cconws("\r\n");
  167.  
  168. timedone:
  169.  
  170.     drive = Dgetdrv();        /* use current drive        */
  171.  
  172.     /* get disk parameters from boot sector */
  173.  
  174.     if (Rwabs (READ, boot, 1, 0, drive) != OK)
  175.         error("\nError reading boot sector!");
  176.     bps = UI(boot, 11);        /* bytes per sector        */
  177.     spc = US(boot, 13);        /* sectors per cluster        */
  178.     res = UI(boot, 14);        /* no. of reserved sec        */
  179.     fats = US(boot, 16);        /* no. of FATs            */
  180.     dir = UI(boot, 17);        /* no. of dir entries        */
  181.     spd = UI(boot, 19);        /* sectors per disk        */
  182.     spf = UI(boot, 22);        /* sectors per FAT        */
  183.     spt = UI(boot, 24);        /* sectors per track        */
  184.     sides = UI(boot, 26);        /* sides of disk        */
  185.     secs = 32 * dir;        /* >>>> 32-byte dir entries    */
  186.     secs /= bps;            /* length of dir in sectors    */
  187.  
  188.     /* find start address of RAM disk */
  189.  
  190.     stack = Super(0L);        /* get into supervisor mode    */
  191.     buf = *((char **) 0x42E);    /* physical top of memory    */
  192.     Super(stack);            /* back to user mode        */
  193.  
  194.     /* adjust RAMdisk BPB */
  195.  
  196.     bpb = (WORD *) buf;        /* RAMdisk BPB area        */
  197.     if (bpb[0] != bps)
  198.         error("\nDisk and RAMdisk incompatible!");    /* >>>>    */
  199.     if (bpb[255] == 0x4144)        /* our own magic number        */
  200.         error("\n\tOld RAM disk!");
  201.     bpb[255] = 0x4144;        /*    "AD"            */
  202.     bpb[1] = spc;
  203.     bpb[2] = bps*spc;
  204.     bpb[3] = secs;
  205.     bpb[4] = spf;
  206.     bpb[5] = spf + res;
  207.     bpb[6] = 2*spf + bpb[3] + res;    /* >>>> assumes 2 FATs        */
  208.  
  209.     /* copy the data from floppy to RAM */
  210.  
  211.     Cconws("\n\tCopying data...\r\n");
  212.  
  213.     buf += 512;            /* start of RAMdisk data area    */
  214.     buf += bps*res;            /* start of FAT area        */
  215.     secs += fats*spf;        /* read FATs + dir        */
  216.     if (Rwabs (READ, buf, secs, res, drive) != OK)
  217.         error(msg);
  218.     res += secs;            /* no. of sectors already read    */
  219.     i = 3*(spd-res);        /* >>>> 12-bit FAT entries    */
  220.     i = 3 + i/spc/2;
  221.     while (buf[--i] == 0);        /* search for last used sector    */
  222.     buf += bps*secs;        /* next place to put stuff    */
  223.     i *= spc*2;
  224.     secs = i/3;            /* no. of sectors left to read    */
  225.     if (secs > spd-res)        /* safety check            */
  226.         secs = spd-res;
  227.     if (Rwabs (READ, buf, secs, res, drive) != OK)
  228.         error(msg);
  229.  
  230.     Cconws("\n\tAUTODISK finished, no errors\r\n");
  231.     for (datime=0; datime<50000; datime++);
  232. }
  233.